package com.xinting.piano.app;

import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.hannesdorfmann.swipeback.Position;
import com.hannesdorfmann.swipeback.SwipeBack;
import com.xinting.piano.R;
import com.xinting.piano.data.PApp;
import com.xinting.piano.data.PColor;
import com.xinting.piano.data.PError;
import com.xinting.piano.data.PUser;
import com.xinting.piano.lib.util.PUtil;
import com.xinting.piano.service.IHandleJson;
import com.xinting.piano.service.PAccount;
import com.xinting.piano.view.PToggleButton;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

/**
 * Created by wuxinting on 15/11/5.
 */
public class PApplyLoginActivity extends PBaseActivity {

    public static final String LOG_TAG = PApp.LOG_TAG+"_a_l_ac";

    private Button applyLoginOk;
    private EditText phoneEdit;
    private EditText passwdEdit;
    private EditText verifyEdit;
    private RelativeLayout verifyContainer;
    private EditText nickEdit;
    private PToggleButton toggleButton;

    //forget password
    private TextView forgetView;
    //提示信息
    private TextView infoView;
    //提示错误
    private TextView errorView;

    private Handler handler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        SwipeBack.attach(this, Position.LEFT)
            .setContentView(R.layout.activity_apply_login)
            .setSwipeBackView(R.layout.swipeback_default);

        handler = new ApplyLoginHandler();

        applyLoginOk = $(R.id.apply_login_ok);
        phoneEdit = $(R.id.phone);
        passwdEdit = $(R.id.passwd);
        verifyEdit = $(R.id.verify);
        nickEdit = $(R.id.nickname);
        toggleButton = $(R.id.apply_or_login);
        verifyContainer = $(R.id.verify_container);

        forgetView = $(R.id.forget_passwd);
        infoView = $(R.id.apply_login_info);
        errorView = $(R.id.apply_login_error);

        TextWatcher watcher = new ApplyLoginTextWatcher();
        phoneEdit.addTextChangedListener(watcher);
        passwdEdit.addTextChangedListener(watcher);

        View.OnFocusChangeListener focusChangeListener = new ApplyLoginEditFocusChangeListener();
        phoneEdit.setOnFocusChangeListener(focusChangeListener);
        passwdEdit.setOnFocusChangeListener(focusChangeListener);
        verifyEdit.setOnFocusChangeListener(focusChangeListener);

        View.OnClickListener clickListener = new OnApplyLoginOkListener();
        toggleButton.setOnClickListener(clickListener);
        applyLoginOk.setOnClickListener(clickListener);

        forgetView.setOnClickListener(new ForgetPasswordListener());
    }

    /**
     * forget password
     */
    private class ForgetPasswordListener implements View.OnClickListener {

        @Override
        public void onClick(View view) {
            verifyEdit.setVisibility(View.VISIBLE);
            infoView.setText($s(R.string.a_l_forget_password));
        }
    }

    /**
     * 监听编辑框中的各项事件，进行较验操作和提示
     */
    private class ApplyLoginTextWatcher implements TextWatcher {

        @Override
        public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
            infoView.setText("");
            errorView.setText("");
        }

        @Override
        public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
            View v = getCurrentFocus();
            if (v instanceof EditText == false) {
                return;
            }

            EditText text = (EditText) v;
            boolean legal;

            //较验手机号
            legal = text == phoneEdit ? PUtil.checkPhoneNumber(charSequence.toString()) :
                        //较验密码
                        (text == passwdEdit ? PUtil.checkPasswd(charSequence.toString()) :
                            //检验昵称
                            (text == nickEdit ? PUtil.checkNickName(charSequence.toString()) :
                                //检验验证码
                                (text == verifyEdit && PUtil.checkVerifyCode(charSequence.toString()))));

            if (!legal) {
                text.setTextColor(PColor.METAL_RED);
            } else {
                text.setTextColor(PColor.METAL_BLACK);
            }

        }

        @Override
        public void afterTextChanged(Editable editable) {
        }
    }

    /**
     * 编辑框转换事件，发送验证码
     */
    private class ApplyLoginEditFocusChangeListener implements View.OnFocusChangeListener {

        @Override
        public void onFocusChange(View view, boolean b) {
            PAccount.Status status = PAccount.getInstance().getStatus();
            if (b) {
                if (view == verifyEdit && status == PAccount.Status.LOGOUT) {
                    PAccount.getInstance().sendVerifyCode(phoneEdit.getText().toString(), new HandleAccountResult());
                }
            }

            //失去焦点的情况
            if (!b) {
                PError check;
                if (toggleButton.isChecked()) {
                    check = checkLoginParams(false);
                } else {
                    check = checkApplyParams(false);
                }

                if (!check.isSuccess()) {
                    errorView.setText(check.getMsg());
                    PUtil.toast(PApp.getAppContext(), check.getMsg());
                }
            }
        }
    }

    /**
     * 点击ok,或者登录注册切换事件，注册或者登录
     */
    private class OnApplyLoginOkListener implements View.OnClickListener {

        @Override
        public void onClick(View view) {
            if (view == toggleButton) {
                infoView.setText("");
                errorView.setText("");
                forgetView.setVisibility(View.GONE);
                if (toggleButton.isChecked()) {
                    //login
                    verifyContainer.setVisibility(View.GONE);
                    nickEdit.setVisibility(View.GONE);
                    verifyEdit.setText("");
                } else {
                    verifyContainer.setVisibility(View.VISIBLE);
                    nickEdit.setVisibility(View.VISIBLE);
                }
            } else {
                //隐藏软键盘
                PUtil.showSoftInput(getCurrentFocus(), false);

                String phone = phoneEdit.getText().toString();
                String passwd = passwdEdit.getText().toString();
                String verify = verifyEdit.getText().toString();
                String nickname = nickEdit.getText().toString();

                PUser user = new PUser();
                user.setPhone(phone);

                try {
                    nickname = URLEncoder.encode(nickname, "UTF-8");
                } catch (UnsupportedEncodingException e) {
                    Log.e(LOG_TAG, "Encode nick failed. " + e.toString());
                }
                user.setNick(nickname);

                PError check;
                if (toggleButton.isChecked()) {
                    // login
                    check = checkLoginParams(true);
                    if (check.getCode() == PError.ERR_SUCCESS) {
                        PAccount.getInstance().login(user, passwd, verify, new HandleAccountResult());
                    }
                } else {
                    // apply
                    check = checkApplyParams(true);
                    if (check.getCode() == PError.ERR_SUCCESS) {
                        PAccount.getInstance().apply(user, passwd, verify, new HandleAccountResult());
                    }
                }

                if (check.getCode() != PError.ERR_SUCCESS) {
                    errorView.setText(check.getMsg());
                    PUtil.toast(PApp.getAppContext(), check.getMsg());
                }
            }

        }
    }

    //handle the result return from PAccount
    private class HandleAccountResult implements IHandleJson {

        @Override
        public void handleJson(JSONObject json) {
            Message msg = Message.obtain();
            msg.obj = json;
            handler.sendMessage(msg);
        }
    }

    //handle the result and update ui
    private class ApplyLoginHandler extends Handler {

        @Override
        public void handleMessage(Message message) {
            if (message.obj instanceof JSONObject == false) return;

            JSONObject json = (JSONObject) message.obj;
            Log.v(PApp.LOG_TAG, json.toString());

            // 对返回结果作UI响应
            if (toggleButton.isChecked()) {
                tipLoginResult(json);
            } else {
                tipApplyResult(json);
            }

            //login success, start next activity
            if (PAccount.getInstance().getStatus() == PAccount.Status.LOGIN) {
                toNextActivity();
            }
        }
    }

    /**
     * check username, password, verifycode, nickname
     * @return return if any one incorrect
     */
    private PError checkApplyParams(boolean isCheckEmpty) {
        PError error = checkLoginParams(isCheckEmpty);
        if (error.getCode() != PError.ERR_SUCCESS) {
            return error;
        }

        String verify = verifyEdit.getText().toString();
        String nickname = nickEdit.getText().toString();

        if ((!verify.isEmpty() || isCheckEmpty) && !PUtil.checkVerifyCode(verify)) {
            error.setCode(PError.ERR_NOT_VERIFY);
            error.setMsg($s(R.string.a_l_not_verify));
            return error;
        }

        if ((!nickname.isEmpty() || isCheckEmpty) && !PUtil.checkNickName(nickname)) {
            error.setCode(PError.ERR_NOT_NICK);
            error.setMsg($s(R.string.a_l_not_nickname));
            return error;
        }
        return error;
    }

    /**
     * check username, password
     * @param isCheckEmpty 是否检验空值
     * @return
     */
    private PError checkLoginParams(boolean isCheckEmpty) {
        PError error = new PError();
        error.setCode(PError.ERR_SUCCESS);
        error.setMsg("");

        String phone = phoneEdit.getText().toString();
        String passwd = passwdEdit.getText().toString();

        if ((!phone.isEmpty() || isCheckEmpty) && !PUtil.checkPhoneNumber(phone)) {
            error.setCode(PError.ERR_NOT_PHONE);
            error.setMsg($s(R.string.a_l_not_phone));
            return error;
        }

        if ((!passwd.isEmpty() || isCheckEmpty) && !PUtil.checkPasswd(passwd)) {
            error.setCode(PError.ERR_NOT_PASSWORD);
            error.setMsg($s(R.string.a_l_not_passwd));
            return error;
        }
        return error;
    }

    /**
     * 注册结果的提示
     * @param json
     * @return 如果json结果是成功，返回true
     */
    private boolean tipApplyResult(JSONObject json) {
        Log.i(LOG_TAG, "Tip Apply Result");
        PError error = new PError();
        error.fromJson(json);

        CharSequence msg = "";

        switch (error.getCode()) {
            case PError.ERR_REPEAT:
                // 重复的用户名
                msg = $s(R.string.a_l_repeat_user);
                errorView.setText(msg);
                break;
            case PError.ERR_VERIFY_SENT:
                msg = $s(R.string.verfiy_sent);
                verifyEdit.setHint(msg);
                infoView.setText(msg);
                break;
            case PError.ERR_VERIFY_SEND_FAIL:
                msg = $s(R.string.a_l_verify_send_fail);
                errorView.setText(msg);
                break;
            case PError.ERR_VERIFY_INCORRECT:
                msg = $s(R.string.a_l_verify_incorrect);
                errorView.setText(msg);
                break;
            case PError.ERR_REPEAT_NICK:
                msg = error.getMsg();
                errorView.setText(msg);
                break;
            case PError.ERR_SUCCESS:
                msg = $s(R.string.apply_success);
                infoView.setText(msg);
                break;
        }

        PUtil.toast(PApp.getAppContext(), msg);
        return error.isSuccess();
    }

    /**
     * 登录结果的提示
     * @param json
     * @return 如果json结果是成功，返回true
     */
    private boolean tipLoginResult(JSONObject json) {
        Log.i(LOG_TAG, "Tip Login Result");
        int code = json.optInt(PError.KEY_CODE, PError.ERR_UNKNOWN);
        CharSequence msg = "";

        switch (code) {
            case PError.ERR_AUTH_FAIL:
                //如果密码错误，将进入忘记密码流程
                msg = json.optString(PError.KEY_MSG, "");
                forgetView.setVisibility(View.VISIBLE);
                errorView.setText(msg);
                break;
            case PError.ERR_VOID_USER:
                //登录时，错误的用户名
                msg = $s(R.string.a_l_void_user);
                errorView.setText(msg);
                break;
            case PError.ERR_VERIFY_INCORRECT:
                msg = $s(R.string.a_l_verify_incorrect);
                errorView.setText(msg);
                break;
            case PError.ERR_SUCCESS:
                msg = $s(R.string.login_success);
                infoView.setText(msg);
                break;
        }

        PUtil.toast(PApp.getAppContext(), msg);
        return code == PError.ERR_SUCCESS;
    }

    /**
     * jump to next activity
     */
    private void toNextActivity() {
        Intent intent = new Intent();

        String next = getIntent().getStringExtra(PApp.KEY_NEXT);
        try {
            if (next == null) {
                next = PMainActivity.class.getName();
            }
            Class nextActivity = Class.forName(next);
            intent.setClass(PApplyLoginActivity.this, nextActivity);
        } catch (ClassNotFoundException e) {
            intent.setClass(PApplyLoginActivity.this, PMainActivity.class);
        }
        intent.putExtra(PUser.KEY, PAccount.getInstance().getCurrentUser());
        startActivity(intent);

        finish();
    }
}
